use strict;
use warnings;

package Lingua::EN::WSD::WebBased::Expander;

use Class::AccessorMaker {
    max_retries     => 10,
    expansion_size  => 32,
    enable_cache    => 1,
    cache_file      => 'expander_cache',
    cache           => { }
}, 'new_init';

use DB_File;
use Storable qw/thaw freeze/;

use Lingua::EN::WSD::WebBased::Logger;

sub init {

    my $self = shift;

    if ($self->enable_cache) {

        tie my %cache, 'DB_File', $self->cache_file,
            O_CREAT | O_RDWR, 0644, $DB_BTREE;
        $self->cache(\%cache);
        _trace("open cache: ", $self->cache_file);

    }

}

sub hit_in_cache {

    my ($self, $query) = @_;

    if (exists $self->cache->{$query}) {
        _trace('hit in expander cache');
        return thaw($self->cache->{$query});
    }
    else {
        _trace('not hit in expander cache');
        return undef;
    }

}

sub store_in_cache {

    my ($self, $query, $documents) = @_;

    $self->cache->{$query} = freeze($documents);
    (tied %{$self->cache})->sync();

}

# expand seed queries to documents

sub expand {

    my ($self, $queries) = @_;

    _trace(__PACKAGE__, '::expand(', join(", ", @$queries), ')');

    my @documents;
    my $size = $self->expansion_size;

    for my $query (@$queries) {

        $query = "$query -\"youtube\" -\"google video\"";

        my $cached_documents;
        $cached_documents = $self->hit_in_cache($query) if $self->enable_cache;
        
        if ($self->enable_cache &&
            defined $cached_documents &&
            @$cached_documents >= $size)
        {
            push @documents, (@$cached_documents)[0 .. $size - 1];
        }
        else {
            my $documents = undef;
            my $retries = 0;
            do {
                _warn("retry #$retries") if $retries > 0;
                $retries++;
                $documents = $self->search($query, $self->expansion_size);
            } while ($retries <= $self->max_retries && !defined $documents);
            if ($retries >= $self->max_retries && !defined $documents) {
                _error('reach maximum retries, searching abort');
            }
            else {            
                push @documents, @$documents;
                $self->store_in_cache($query, $documents) if $self->enable_cache;
            }
        }

    }
    
    return \@documents;

}


1;
